package com.easychat.service.impl;

import com.easychat.common.LeaseException;
import com.easychat.dto.MessageSendDto;
import com.easychat.dto.SysSettingDto;
import com.easychat.dto.TokenUserInfoDto;
import com.easychat.dto.UserContactSearchResultDto;
import com.easychat.entity.*;
import com.easychat.entity.constants.Constants;
import com.easychat.entity.query.UserContactQuery;
import com.easychat.enums.*;
import com.easychat.mappers.*;
import com.easychat.redis.RedisComponent;
import com.easychat.service.UserContactApplyService;
import com.easychat.service.UserContactService;
import com.easychat.utils.StringTools;
import com.easychat.websocket.MessageHandler;
import org.hibernate.validator.internal.engine.messageinterpolation.parser.MessageState;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * (UserContact)表服务实现类
 *
 * @author makejava
 * @since 2024-10-08 20:08:24
 */
@Service("userContactService")
public class UserContactServiceImpl implements UserContactService {
    @Resource
    private UserContactDao userContactDao;
    @Resource
    private UserInfoDao userInfoDao;
    @Resource
    private GroupInfoDao groupInfoDao;
    @Resource
    private UserContactApplyDao userContactApplyDao;
    @Resource
    private UserContactApplyService userContactApplyService;
    @Resource
    private RedisComponent redisComponent;
    @Resource
    private ChatSessionDao chatSessionDao;
    @Resource
    private ChatSessionUserDao chatSessionUserDao;
    @Resource
    private ChatMessageDao chatMessageDao;
    @Resource
    private MessageHandler messageHandler;

    /**
     * 通过ID查询单条数据
     *
     * @param userId 主键
     * @return 实例对象
     */
    @Override
    public UserContact queryById(String userId) {
        return this.userContactDao.queryById(userId);
    }

    /**
     * 分页查询
     *
     * @param userContact 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<UserContact> queryByPage(UserContact userContact, PageRequest pageRequest) {
        long total = this.userContactDao.count(userContact);
        return new PageImpl<>(this.userContactDao.queryAllByLimit(userContact, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param userContact 实例对象
     * @return 实例对象
     */
    @Override
    public UserContact insert(UserContact userContact) {
        this.userContactDao.insert(userContact);
        return userContact;
    }

    /**
     * 修改数据
     *
     * @param userContact 实例对象
     * @return 实例对象
     */
    @Override
    public UserContact update(UserContact userContact) {
        this.userContactDao.update(userContact);
        return this.queryById(userContact.getUserId());
    }

    /**
     * 通过主键删除数据
     *
     * @param userId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(String userId) {
        return this.userContactDao.deleteById(userId) > 0;
    }

    /**
     * 根据userId和groupId查询群组联系
     * @param userId
     * @param groupId
     * @return
     */
    @Override
    public UserContact getUserContactByUserIdAndContactId(String userId, String groupId) {
        UserContact userContact = userContactDao.selectByUserIdAndGroupId(userId,groupId);
        return userContact;
    }

    @Override
    public UserContactSearchResultDto searchContact(String userId, String contactId) {
        //判断是搜索的是群组还是人
        UserContactTypeEnum typeEnum = UserContactTypeEnum.getByPrefix(contactId);
        if(typeEnum == null){
            return null;
        }
        UserContactSearchResultDto searchResultDto = new UserContactSearchResultDto();
        switch (typeEnum){
            case USER:
                UserInfo userInfo = userInfoDao.queryById(contactId);
                if(userInfo == null){
                    return null;
                }
                BeanUtils.copyProperties(userInfo,searchResultDto);
                break;
            case GROUP:
                GroupInfo groupInfo = groupInfoDao.selectByGroupId(contactId);
                if(groupInfo == null){
                    return null;
                }
                searchResultDto.setNickName(groupInfo.getGroupName());
                break;
        }
        searchResultDto.setContactType(typeEnum.toString());
        searchResultDto.setContactId(contactId);
        if(userId.equals(contactId)){
            searchResultDto.setStatus(1);
            return searchResultDto;
        }
        //查询是否是好友
        UserContact userContact = userContactDao.selectByUserIdAndGroupId(userId, contactId);
        searchResultDto.setStatus(userContact==null?null: userContact.getStatus());

        return searchResultDto;
    }

    @Override
    @Transactional
    public Integer applyAdd(TokenUserInfoDto tokenUserInfoDto, String contactId, String applyInfo) {
        UserContactTypeEnum typeEnum = UserContactTypeEnum.getByPrefix(contactId);
        if(null == typeEnum){
            throw new LeaseException(ExceptionCodeEnum.ERROR_REQUEST);
        }
        //申请人
        String applyUserId = tokenUserInfoDto.getUserId();
        //默认申请信息
        applyInfo = applyInfo==null? String.format(Constants.APPLY_INFO_TEMPLATE,tokenUserInfoDto.getNickName()):applyInfo;
        //系统从1970年1月1日00:00:00 到当前时间经过的毫秒数
        long curTime = System.currentTimeMillis();
        Integer joinType = null;
        String receiveUserId = contactId;

        //查询对方好友是否已经添加，如果已经拉黑无法添加
        UserContact userContact = userContactDao.selectByUserIdAndGroupId(applyUserId, receiveUserId);
        if(userContact != null && userContact.getStatus() == 5){
            throw new LeaseException("对方已将你拉黑");
        }
        if(UserContactTypeEnum.GROUP == typeEnum){
            GroupInfo groupInfo = groupInfoDao.selectByGroupId(contactId);
            if(groupInfo==null || 0 == groupInfo.getStatus()){
                throw new LeaseException("群聊不存在或已解散");
            }
            receiveUserId = groupInfo.getGroupOwnerId();
            joinType = groupInfo.getJoinType();
        }else {
            UserInfo userInfo = userInfoDao.queryById(contactId);
            if (userInfo == null){
                throw new LeaseException("添加人不存在");
            }
            joinType = userInfo.getJoinType();
        }
            //直接加入不用记录申请记录
        if(joinType == 0){
            userContactApplyService.addContact(applyUserId,receiveUserId,contactId,typeEnum.getType(),applyInfo);
            return joinType;
        }
        UserContactApply dbApply = userContactApplyDao.selectByApplyUserIdAndReceiveUserIdAndContactId(applyUserId, receiveUserId, contactId);
        if(dbApply == null){
            UserContactApply userContactApply = new UserContactApply();
            userContactApply.setApplyUserId(applyUserId);
            userContactApply.setContactType(typeEnum.getType());
            userContactApply.setReceiveUserId(receiveUserId);
            userContactApply.setLastApplyTime(curTime);
            userContactApply.setContactId(contactId);
            userContactApply.setStatus(UserContactApplyStatusEnum.INIT.getStatus());
            userContactApply.setApplyInfo(applyInfo);
            userContactApplyDao.insert(userContactApply);
        }else {
            //更新状态
            UserContactApply userContactApply = new UserContactApply();
            userContactApply.setStatus(UserContactApplyStatusEnum.INIT.getStatus());
            userContactApply.setLastApplyTime(curTime);
            userContactApply.setApplyInfo(applyInfo);
            userContactApplyDao.update(userContactApply,dbApply.getApplyId());
        }
        if(dbApply == null || !UserContactApplyStatusEnum.INIT.getStatus().equals(dbApply.getStatus())){
            //发送ws消息
            MessageSendDto messageSendDto = new MessageSendDto();
            messageSendDto.setMessageType(MessageTypeEnum.CONTACT_APPLY.getType());
            messageSendDto.setMessageContent(applyInfo);
            messageSendDto.setContactId(receiveUserId);
            messageHandler.sendMessage(messageSendDto);
        }

        return joinType;
    }

    /**
     * 查询用户的好友或群聊列表
     * @param userContactQuery
     * @return
     */
    @Override
    public List<UserContact> selectUserOrGroupList(UserContactQuery userContactQuery) {
        List<UserContact> contactList = userContactDao.selectList(userContactQuery);
        return contactList;
    }

    @Override
    public void removeUserContact(String userId, String contactId, Integer statusEnum) {
        //移除好友
        UserContact userContact = new UserContact();
        userContact.setStatus(statusEnum);
        userContactDao.updateByUserIdAndContactId(userContact,userId,contactId);

        //将好友中也移除自己
        UserContact friendContact = new UserContact();
        if(2 == statusEnum){
            friendContact.setStatus(3);//被删除
        }else if (4 == statusEnum){
            friendContact.setStatus(5); //被拉黑
        }
        userContactDao.updateByUserIdAndContactId(friendContact,contactId,userId);
        // 从我的好友列表缓存中删除好友
        redisComponent.removeUserContact(userId,contactId);
        redisComponent.removeUserContact(contactId,userId);
        //从好友列表缓存中删除我
    }

    @Override
    @Transactional
    public void addContact4Robot(String userId) {
        Date curDate = new Date();
        SysSettingDto sysSetting = redisComponent.getSysSetting();
        String contactId = sysSetting.getRobotUid();
        String contactName = sysSetting.getRobotNickName();
        String sendMessage = sysSetting.getRobotWelcome();
        sendMessage  = StringTools.cleanHtmlTag(sendMessage);
        //增加机器人好友
        UserContact userContact = new UserContact();
        userContact.setUserId(userId);
        userContact.setContactId(contactId);
        userContact.setContactType(UserContactTypeEnum.USER.getType());
        userContact.setCreateTime(curDate);
        userContact.setLastUpdateTime(curDate);
        userContact.setStatus(UserContactStatusEnum.FRIEND.getStatus());
        userContactDao.insert(userContact);
        //增加会话信息
        String sessionId = StringTools.getChatSessionId4User(new String[]{userId,contactId});
        ChatSession chatSession = new ChatSession();
        chatSession.setLastMessage(sendMessage);
        chatSession.setSessionId(sessionId);
        chatSession.setLastReceiveTime(curDate.getTime());
        chatSessionDao.insert(chatSession);

        //增加会话人信息
        ChatSessionUser chatSessionUser = new ChatSessionUser();
        chatSessionUser.setUserId(userId);
        chatSessionUser.setContactId(contactId);
        chatSessionUser.setContactName(contactName);
        chatSessionUser.setSessionId(sessionId);
        chatSessionUserDao.insert(chatSessionUser);

        //增加聊天消息
        ChatMessage chatMessage = new ChatMessage();
        chatMessage.setSessionId(sessionId);
        chatMessage.setMessageType(MessageTypeEnum.CHAT.getType());
        chatMessage.setMessageContent(sendMessage);
        chatMessage.setSendUserId(contactId);
        chatMessage.setSendUserNickName(contactName);
        chatMessage.setSendTime(curDate.getTime());
        chatMessage.setContactId(userId);
        chatMessage.setContactType(UserContactTypeEnum.USER.getType());
        chatMessage.setStatus(MessageStatusEnum.SENDED.getStatus());
        chatMessageDao.insert(chatMessage);

    }


}
